package br.ufrgs.meetapp.activities;

import android.app.Activity;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.drawable.Drawable;
import android.os.AsyncTask;
import android.os.Bundle;
import android.provider.Settings;
import android.telephony.TelephonyManager;
import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.Window;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.TextView;
import br.ufrgs.meetapp.dialogs.PopupMessage;
import br.ufrgs.meetapp.dialogs.PopupTrackOthers;
import br.ufrgs.meetapp.enums.DeviceProvider;
import br.ufrgs.meetapp.enums.WebServiceResult;
import br.ufrgs.meetapp.location.LocationBasedServices;
import br.ufrgs.meetapp.models.User;
import br.ufrgs.meetapp.utils.ActivityIndicator;
import br.ufrgs.meetapp.utils.UserPreferencesPersistence;

public class LoginActivity extends Activity implements OnClickListener {
	
	public static final int LOGIN_TYPE_INVALID = -1;
	public static final int LOGIN_TYPE_CONSUMER = 0;
	public static int LOGIN_TYPE_ENTERPRISE = 1;
	
	private Button buttonNoRegistration;
	private Button buttonConsumerLogin;
	private Button buttonForgotPassword;
	private Button buttonLogin;

	private EditText editTextCustomer;
	private EditText editTextUsername;
	private EditText editTextPassword;
	
	private Drawable originalEditTextDrawableCustomer;
	private Drawable originalEditTextDrawableUsername;
	private Drawable originalEditTextDrawablePassword;
	
	private CheckBox checkBoxSaveLogin;

	private PopupMessage errorPopup;
	private String errorBody;
	
	private ActivityIndicator activityIndicator;
	
	public static User loggedUser;
	private User userCandidate;
	private Context context;
	
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);

		requestWindowFeature(Window.FEATURE_CUSTOM_TITLE);
		setContentView(R.layout.login_activity);
		
		context = this;
		activityIndicator = new ActivityIndicator(this);
		userCandidate = new User();
		
		setTitleBar();

		setButtons();

		setEditTexts();

		setCheckBox();
	
	}
	
	/***
	 * Sets login type according to shared preferences
	 */
	private void setLoginType() {
		
		int loginType = 0;
			loginType = LOGIN_TYPE_CONSUMER;
			setConsumerLoginLayout();
		
		UserPreferencesPersistence.setLoginType(context, loginType);
	}
	
	/***
	 * Adds the current device known information, obtained from the context, to the specified device
	 * @param device
	 * @param context
	 */
	public static void setCurrentUserDeviceInfo(User user, Context context) {
		
		TelephonyManager telephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
		
		//consistency for non-phone devices like tablets that dont have IMEI
		if(telephonyManager.getDeviceId() != null){
			user.setDeviceIMEI(telephonyManager.getDeviceId());
		}else {
			Log.i("MFT","ANDROID_ID: "+Settings.Secure.ANDROID_ID);
			user.setDeviceIMEI(Settings.Secure.ANDROID_ID);
		}
		user.setDeviceProvider(DeviceProvider.ANDROID);
		user.setDevicePhoneNumber(telephonyManager.getLine1Number());
	}

	@Override
	public void onResume() {
		super.onResume();
		
		checkGPSAvailability();
		
		checkLoginPreferences();
	}
	
	/***
	 * Sets the login layout according to preferences and if needed try to login directly
	 */
	private void checkLoginPreferences(){
		
		setLoginType();
		
		// Verify if the direct login option is set, if so try to login directly
		String userName = UserPreferencesPersistence.getUserName(context);
		String password = UserPreferencesPersistence.getPassword(context);
		String customer = UserPreferencesPersistence.getCustomer(context);
		
		if ((UserPreferencesPersistence.getLoginOnce(context) 
				|| UserPreferencesPersistence.getSaveLogin(context))
				&& !userName.equals("") 
				&& !password.equals("")
				&& !customer.equals("")
				&& UserPreferencesPersistence.getLoginType(context) != -1) {
			
			editTextUsername.setText(userName);
			editTextPassword.setText(password);
			editTextCustomer.setText(customer);
			
			verifyLogin();
		} else {
			loggedUser = null;
		}
	}

	/***
	 * Sets the top bar
	 */
	private void setTitleBar() {
		// set titleBar
		getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE,
				R.layout.title_bar);
		TextView titleBarTitle = (TextView) findViewById(R.id.title_bar_text_title);
		titleBarTitle.setText(R.string.login_title);
	}

	/***
	 * Set the references to the buttons
	 */
	private void setButtons() {

		buttonLogin = (Button) findViewById(R.id.login_activity_button_login);
		buttonLogin.setOnClickListener(this);

		buttonNoRegistration = (Button) findViewById(R.id.login_activity_button_no_registration);
		buttonNoRegistration.setOnClickListener(this);

		buttonConsumerLogin = (Button) findViewById(R.id.login_activity_button_consumer_login);
		buttonConsumerLogin.setOnClickListener(this);
		
		buttonForgotPassword = (Button) findViewById(R.id.login_activity_button_forgot_password);
		buttonForgotPassword.setOnClickListener(this);
		
//		buttonEnterpriseLogin = (Button) findViewById(R.id.login_activity_button_enterprise_login);
//		buttonEnterpriseLogin.setOnClickListener(this);

	}

	/***
	 * Set the references to the edit texts
	 */
	private void setEditTexts() {

		editTextCustomer = (EditText) findViewById(R.id.login_activity_text_customer);

		editTextUsername = (EditText) findViewById(R.id.login_activity_text_user);

		editTextPassword = (EditText) findViewById(R.id.login_activity_text_password);
		
		originalEditTextDrawableCustomer = editTextCustomer.getBackground();
		originalEditTextDrawableUsername = editTextUsername.getBackground();
		originalEditTextDrawablePassword = editTextPassword.getBackground();
		
	}

	/***
	 * Set the check box reference
	 */
	private void setCheckBox() {
		checkBoxSaveLogin = (CheckBox) findViewById(R.id.login_activity_checkbox_save);
	}

	@Override
	public void onClick(View button) {

		switch (button.getId()) {
		case R.id.login_activity_button_login:
		
			verifyLogin();
			
			break;
		case R.id.login_activity_button_no_registration:
			unsetSaveLoginOption();
			startActivity(new Intent(getApplicationContext(), RegisterActivity.class));
			break;
		default:
			break;
		}
	}
	
	public void unsetSaveLoginOption() {
		UserPreferencesPersistence.setSaveLogin(context, false);
		UserPreferencesPersistence.setLoginOnce(context, false);
	}

	/***
	 * Sets the activity layout to consumer login
	 */
	private void setConsumerLoginLayout() {
		
		checkBoxSaveLogin.setChecked(true);
		
		resetErrorBorders();
		resetFields();
		
//		buttonEnterpriseLogin.setVisibility(View.VISIBLE);
		buttonConsumerLogin.setVisibility(View.GONE);

		editTextCustomer.setVisibility(View.GONE);
		editTextUsername.requestFocus();
		
	}
	
	/**
	 * Clean all the input fields
	 */
	private void resetFields() {
		
		editTextCustomer.setText("");
		editTextPassword.setText("");
		editTextUsername.setText("");
	}
	
	/***
	 * Verify login both locally and server side
	 */
	private void verifyLogin() {
		errorBody = "";
		
		if (isLoginLocallyValid()) {
			
			//TODO: make login
			
			// Fire asynchronous task to verify login at server side
//			new VerifyLoginTask().execute();
			
			startActivity(new Intent(context, TrackOthersTabActivity.class));
			
		} else {
			setLoginIncorrect();
		}
	}
	
	/***
	 * Asynchronous task to call the Web service to verify the user login and show the activity indicator
	 * @author Benites
	 *
	 */
	private class VerifyLoginTask extends AsyncTask<Void, Void, Void> {
		
		private String companyName;
		
		@Override
		protected void onPreExecute(){
			
			findViewById(R.id.login_activity_root_view).post(new Runnable() {
			   public void run() {
				   activityIndicator.show();
			   }
			});
		}
		
		@Override
		protected Void doInBackground(Void... voids) {
			
			//TODO: CHECK LOGIN IN SERVER
			
			
			return null;
		}
		
		@Override
		protected void onPostExecute(Void result) {
			
			startActivity(new Intent(context, TrackOthersTabActivity.class));
		}
	}
	
	/***
	 * Redirect to the right activity or show the right message accordingly to the local error or web service error  
	 */
	private void setLoginIncorrect(){
		
		loggedUser = null;
		
		activityIndicator.dismiss();
		
		errorPopup = new PopupMessage(this,
				getString(R.string.login_error), errorBody,
				getString(R.string.ok_button), null);
		errorPopup.display();
		
	}

	/***
	 * Verify either the login is valid in the server or in the client
	 */
	private boolean isLoginLocallyValid() {

		boolean isLocallyValid = true;

		resetErrorBorders();

		if (editTextUsername.getText().toString().equals("")) {
			setUserNameError();
			isLocallyValid = false;
		}

		if (editTextPassword.getText().toString().equals("")) {
			setPasswordError();
			isLocallyValid = false;
		}

		return isLocallyValid;
	}

	/***
	 * Set the dialog error body with the username error and color the username
	 * edit text borders
	 */
	private void setUserNameError() {
		errorBody += getString(R.string.username_error) + "\n";
		editTextUsername.setBackgroundResource(R.drawable.error_border);
	}

	/***
	 * Set the dialog error body with the password error and color the password
	 * edit text borders
	 */
	private void setPasswordError() {
		errorBody +=  getString(R.string.password_error) + "\n";
		editTextPassword.setBackgroundResource(R.drawable.error_border);
	}
	
	/***
	 * Set the borders around the edit texts to the default style
	 */
	private void resetErrorBorders() {
		editTextUsername.setBackgroundDrawable(originalEditTextDrawableUsername);
		editTextPassword.setBackgroundDrawable(originalEditTextDrawablePassword);
		editTextCustomer.setBackgroundDrawable(originalEditTextDrawableCustomer);
	}

	/**
	 * Create the hard-button menu
	 */
	public boolean onCreateOptionsMenu(Menu menu) {
		super.onCreateOptionsMenu(menu);
		MenuInflater menuInflater = getMenuInflater();
		menuInflater.inflate(R.menu.menu_about, menu);
		return true;
	}

	/**
	 * Actions to the hard-button menu
	 */
	public boolean onOptionsItemSelected(MenuItem item) {
		Intent intent;
		switch (item.getItemId()) {
		case R.id.menuAbout:
			intent = new Intent(getApplicationContext(), AboutActivity.class);
			startActivity(intent);
			return true;
		}

		return false;
	}

	/**
	 * Set LoginActivity as a Main Activity.
	 */
	@Override
	public void onBackPressed() {
		Intent intent = new Intent(Intent.ACTION_MAIN);
		intent.addCategory(Intent.CATEGORY_HOME);
		intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
		startActivity(intent);
	    return;
	}

	/**
	 * Checks whether location services are available and inform user
	 */
	public void checkGPSAvailability() {
		if (!LocationBasedServices.isGpsEnabled(this)) {
			String title = getString(R.string.warning_attention);
			String message = getString(R.string.warning_no_gps_message);
			String firstButtonName = getString(R.string.warning_no_gps_first_button);
			String secondButtonName = getString(R.string.warning_no_gps_second_button);

			DialogInterface.OnClickListener warningNoGPSFirstButtonListner = new DialogInterface.OnClickListener() {
				@Override
				public void onClick(DialogInterface dialog, int which) {
					Intent notificationIntent = new Intent(
							android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS);
					startActivity(notificationIntent);
				}

			};

			PopupMessage noGPSMessage = new PopupMessage(this, title,
					message, firstButtonName, secondButtonName,
					warningNoGPSFirstButtonListner, null);
			noGPSMessage.display();
		}
	}
}